package cn.xshi.bpm.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.xshi.bpm.model.LcDeploymentHis;
import cn.xshi.bpm.model.LcProcess;
import cn.xshi.bpm.param.LcReceiveNParam;
import cn.xshi.bpm.param.original.StartParam;
import cn.xshi.bpm.service.LcDeploymentHisService;
import cn.xshi.bpm.service.LcProcessService;
import cn.xshi.bpm.service.LcTaskService;
import cn.xshi.bpm.service.OriginalService;
import cn.xshi.bpm.util.ActivitiUtil;
import cn.xshi.bpm.vo.ActivityProcessStatusEntity;
import cn.xshi.common.base.BaseResult;
import cn.xshi.common.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Desc 原生态引擎处理服务
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Service
@Slf4j
public class OriginalServiceImpl implements OriginalService {

    @Resource
    LcProcessService lcProcessService;

    @Resource
    LcDeploymentHisService lcDeploymentHisService;

    @Resource
    ActivitiUtil activitiUtil;

    @Resource
    LcTaskService lcTaskService;

    /**
     * 根据部署编号及其它条件发起流程实例（其它条件可省略，原生态）
     * @param startParam
     * @return
     */
    public BaseResult<ActivityProcessStatusEntity> startProcessInstance(StartParam startParam){

        LcDeploymentHis lcDeploymentHis = null;

        if(null == startParam){
            return BaseResult.fail("参数对象为空");
        }
        if(StringUtil.isEmpty(startParam.getDeploymentId()) && StringUtil.isEmpty(startParam.getModuleKey())){
            return BaseResult.fail("部署编号或模块Key必须至少有一项不为空");
        }
        boolean isByModuleKey = false;
        if(!StringUtil.isEmpty(startParam.getDeploymentId())){
            lcDeploymentHis = lcDeploymentHisService.getLcDeploymentHisByDeploymentId(startParam.getDeploymentId());
        }
        if(null == lcDeploymentHis){
            isByModuleKey = true;
        }
        if(isByModuleKey){
            if(!StringUtil.isEmpty(startParam.getModuleKey())){
                LcProcess lcProcess = lcProcessService.getLcProcessByModuleKey(startParam.getModuleKey());
                if(null == lcProcess){
                    return BaseResult.fail("未能获取到模块key");
                }
                Map<String,Object> condition = new HashMap<>();
                condition.put("lcProcessId",lcProcess.getId());
                condition.put("version",startParam.getVersion());//流程定义版本号 配合模块key使用（注意 如果版本号为空 则采用模块Key下最新流程定义）
                lcDeploymentHis = lcDeploymentHisService.getLcDeploymentHisNewUnique(condition);//过滤条件为关闭状态
            }
        }

        if(null == lcDeploymentHis){
            return BaseResult.fail("部署信息不存在");
        }

        if(lcDeploymentHis.getProcessStatus() == 0){
            return BaseResult.fail("主流程信息为待发布状态，操作失败");
        }

        if(lcDeploymentHis.getProcessStatus() == 2){
            return BaseResult.fail("主流程信息已关闭，操作失败");
        }

        if(lcDeploymentHis.getProcessDelFlag() == 1){
            return BaseResult.fail("主流程信息已删除，操作失败");
        }

        ProcessDefinition processDefinition = activitiUtil.getProcessDefinition(startParam.getDeploymentId());
        if(null == processDefinition){
            return BaseResult.fail("未能获取到流程定义");
        }
        ProcessInstance processInstance = activitiUtil.startProcessInstanceByKey(processDefinition.getKey(), startParam.getBusinessKey(), startParam.getVariables());
        if(null == processInstance){
            return BaseResult.fail("发起实例失败");
        }
        //判断是否指定节点
        if(!StringUtil.isEmpty(startParam.getActivityId())){
            List<Task> tasks = activitiUtil.findTaskListByInstanceId(processInstance.getProcessInstanceId());
            if(!CollectionUtil.isEmpty(tasks)){
                LcReceiveNParam lcReceiveNParam = new LcReceiveNParam();
                lcReceiveNParam.setTaskId(tasks.get(0).getId());
                lcReceiveNParam.setActivityId(startParam.getActivityId());
                lcReceiveNParam.setEndAllActivityInstances(true);//是否终止其他正在运行的实例 true/false
                activitiUtil.jump(lcReceiveNParam);
            }
        }
        log.info("发起流程实例：{}",processInstance);
        return BaseResult.success(lcTaskService.checkStatus(processInstance.getProcessInstanceId()));
    }
}
